package notification.net;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;

public class DecoderWialon extends FrameDecoder {
	
   private String BytesToString(ChannelBuffer buf, byte delimiter){
	    int end=buf.indexOf(buf.readerIndex(), buf.capacity(),(byte) delimiter);
	    byte[] temp=new byte[end-buf.readerIndex()];
	    buf.readBytes(temp, 0, end-buf.readerIndex());
	    buf.skipBytes(1);
		return new String(temp);
	}
   
   private Double revDouble(ChannelBuffer buf){
     byte[] b=new byte[8];
	 buf.readBytes(b);
	 ChannelBuffer temp=ChannelBuffers.buffer(8);
	 for (int i=0; i<8; ++i) temp.writeByte(b[7-i]);
	 return new Double(temp.readDouble());
   }
	
	private Object Factory(byte typevalue,ChannelBuffer buf){
		switch(typevalue){
		 case 0x1: return BytesToString(buf,(byte)0x00);
		 case 0x2:
           return new posinfo(revDouble(buf),revDouble(buf),revDouble(buf),buf.readShort(),
		     buf.readShort(),buf.readByte());
		 case 0x3: return new Integer(buf.readInt());
		 case 0x4: return revDouble(buf);
		 case 0x5: return new Long(buf.readLong());
		}
		return null;	
	}
	
	@Override
	protected Object decode(ChannelHandlerContext arg0, Channel arg1,ChannelBuffer buf) throws Exception {
	     if (buf.readableBytes() < 4) {
	        return null;
	     }
	     buf.markReaderIndex();
	     int length = Integer.reverseBytes(buf.readInt());
	     //length=71;
	     if (buf.readableBytes() < length) {
	        buf.resetReaderIndex();
	        return null;
	     }  
	     MessageWialon frame = 
	    		 new MessageWialon(length,BytesToString(buf,(byte) 0x00),buf.readInt(),buf.readInt());
	     while(buf.readerIndex()<length){
	         short A=buf.readShort();
	         int B=buf.readInt();
	         byte C=buf.readByte(), D=buf.readByte();
	         frame.bloks.add(new block(A,B,C,D,
	    		   BytesToString(buf,(byte) 0x00),Factory(D,buf),frame.CAST(D))); 
	     }
	     return frame;
	}
}
